/*
 * @Author: hzm 
 * @Date: 2020-06-18 19:39:01 
 * @Last Modified by: hzm
 * @Last Modified time: 2020-06-22 17:19:18
 */
#pragma once
#include <thread>
#include <atomic>
#include <cassert>
#include <vector>
#include <mutex>

#include <event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>

#include "PipeEvent.h"
#include "GlobalDef.h"

namespace HeyIM {

class EventLoop {

public:

    EventLoop(const EventLoop&) = delete;
    EventLoop& operator=(const EventLoop&) = delete;

    EventLoop();
    ~EventLoop();

    bool run();
    void stop();

    bool isRunning() const;
    bool isRunInLoopThread() const;

    void post(VoidParamHandler handler);

    event_base* eventBase() const;


protected:

    void handlePendingFunc();
    void handleStop();

protected:

    std::atomic<bool> m_running;
    std::atomic<bool> m_eventNotify;    //标识是否有事件正在执行
    struct event_base* m_base = nullptr;
    std::thread::id m_tid;

    PipeEventPtr m_pipeEvent = nullptr;

    std::vector<VoidParamHandler> m_pendingFuncs;
    std::mutex m_pendingFuncsMutex;
};

typedef std::shared_ptr<EventLoop> EventLoopPtr;


}


